using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Domain.Entities;
using UniversalAdmin.Domain.Repositories;
using UniversalAdmin.Infrastructure.Data.Contexts;

namespace UniversalAdmin.Infrastructure.Repositories;

public class PermissionRepository : Repository<Permission>, IPermissionRepository
{
    public PermissionRepository(ApplicationDbContext context) : base(context)
    {
    }

    public new async Task<IEnumerable<Permission>> GetAllAsync()
    {
        return await _context.Permissions
            .OrderBy(p => p.SortOrder)
            .ToArrayAsync();
    }

    public async Task<IEnumerable<Permission>> GetEnabledAsync()
    {
        return await _context.Permissions
            .Where(p => p.IsEnabled)
            .OrderBy(p => p.SortOrder)
            .ToArrayAsync();
    }

    public async Task<IEnumerable<Permission>> GetByResourceAsync(string resource)
    {
        return await _context.Permissions
            .Where(p => p.Resource == resource)
            .OrderBy(p => p.SortOrder)
            .ToArrayAsync();
    }

    public async Task<bool> IsUsedByRolesAsync(Guid permissionId)
    {
        return await _context.RolePermissions.AnyAsync(rp => rp.PermissionId == permissionId);
    }

    public async Task<IEnumerable<Permission>> GetByRoleIdAsync(Guid roleId)
    {
        var permissions = await _context.RolePermissions
            .Where(rp => rp.RoleId == roleId)
            .Select(rp => rp.Permission)
            .Where(p => p != null)
            .OrderBy(p => p!.SortOrder)
            .ToArrayAsync();

        return permissions.Where(p => p != null)!;
    }

    public async Task<IEnumerable<Permission>> GetPermissionTreeAsync()
    {
        return await _context.Permissions
            .Where(p => p.IsEnabled)
            .OrderBy(p => p.Resource)
            .ThenBy(p => p.SortOrder)
            .ToArrayAsync();
    }

    public async Task BatchUpdateStatusAsync(List<Guid> permissionIds, bool isEnabled)
    {
        var permissions = await _context.Permissions
            .Where(p => permissionIds.Contains(p.Id))
            .ToListAsync();

        foreach (var permission in permissions)
        {
            permission.IsEnabled = isEnabled;
        }

        await _context.SaveChangesAsync();
    }

    public async Task<object> GetPermissionStatsAsync()
    {
        var totalPermissions = await _context.Permissions.CountAsync();
        var enabledPermissions = await _context.Permissions.CountAsync(p => p.IsEnabled);
        var disabledPermissions = totalPermissions - enabledPermissions;

        var permissionsByType = await _context.Permissions
            .GroupBy(p => p.Type)
            .Select(g => new { type = g.Key, count = g.Count() })
            .ToArrayAsync();

        var permissionsByResource = await _context.Permissions
            .GroupBy(p => p.Resource)
            .Select(g => new { resource = g.Key, count = g.Count() })
            .ToArrayAsync();

        return new
        {
            total = totalPermissions,
            enabled = enabledPermissions,
            disabled = disabledPermissions,
            bytype = permissionsByType,
            byresource = permissionsByResource
        };
    }
}